﻿#region copyright
//<copyright>
// Copyright(C) 2012 TrackerRealm Corporation
// This file is part of the open source project - Jazz. http://jazz.codeplex.com
// 
// Jazz is open software: you can redistribute it and/or modify it 
// under the terms of the GNU Affero General Public License (AGPL) as published by 
// the Free Software Foundation, version 3 of the License.
// 
// Jazz is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty 
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
//  See the GNU Affero General Public License (AGPL) for more details.
// 
// You should have received a copy of the GNU General Public 
// License along with Jazz.  If not, see <http://www.gnu.org/licenses/>.
//
// REMOVAL OF THIS NOTICE IS VIOLATION OF THE COPYRIGHT. 
//</copyright>
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Reflection;
using TrackerRealm.Jazz.Common;

namespace TrackerRealm.Jazz.Client
{
    /// <summary>
    /// 
    /// </summary>
    public class jMethodInfo: jMemberInfo
    {
        internal static jMethodInfo EmptyMethod = new jMethodInfo(null, null){isEmpty = true};
        #region Constructor
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="method"></param>
        /// <param name="jObj"></param>
        internal jMethodInfo(MethodInfo method, jObject jObj)
        :base(method, jObj)
        {
        }
        #endregion
        #region IsPublic
        /// <summary>
        /// Returns true if this method is executable.
        /// </summary>
        public override bool IsPublic
        {
            get
            {
                if (this.MethodInfo != null)  // will be null when Empty
                {
                    if (this.jazzObject != null)
                    {
                        if (!this.jazzObject.IsAccessible) return false;
                        if (this.jazzObject.IsReadOnly && !this.MethodInfo.IsAccessorMethodAttribute()) return false;
                        return this.MethodInfo.IsGrantedAccess(this.jazzObject);
                    }
                    return this.MethodInfo.IsPublic;
                }
                return false;
            }
        }
        #endregion
        #region MethodInfo
        /// <summary>
        /// 
        /// </summary>
        public override MethodInfo MethodInfo
        {
            get { return (MethodInfo)this.member; }
        }
        #endregion
        #region Execute
        /// <summary>
        /// Execute this method.
        /// </summary>
        /// <returns></returns>
        public override object Execute()
        {
            return this.MethodInfo.Invoke(base.jazzObject, new object[0]);
        }
        /// <summary>
        /// Execute this method.
        /// </summary>
        /// <param name="jazzObject"></param>
        /// <returns></returns>
        public override object Execute(jObject jazzObject)
        {
            return this.MethodInfo.Invoke(jazzObject, new object[0]);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="jazzObject"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public override object Execute(jObject jazzObject, params object[] args)
        {
            return this.MethodInfo.Invoke(jazzObject, args);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public override object Execute(params object[] args)
        {
            return this.MethodInfo.Invoke(base.jazzObject, args);
        }
        #endregion

        #region IsGrey
        /// <summary>
        /// Returns true if this member is not accessible due to a "Grant" attribute and this member is otherwise accessible (declared public).
        /// </summary>
        public override bool IsGrey
        {
            // (this.MethodInfo != null && this.MethodInfo.IsPublic)) && <--- if more than 'public' members is supported - this will be required.
            get { return !this.IsPublic &&  this.jazzObject != null; }
        }
        #endregion
        #region IsEmpty
        /// <summary>
        /// 
        /// </summary>
        protected bool isEmpty = false;
        /// <summary>
        /// Returns true if this method is the 'Empty' method.
        /// </summary>
        public override bool  IsEmpty
        {
            get { return this.isEmpty; }
        }
        #endregion
        #region IsRule
        /// <summary>
        /// 
        /// </summary>
        public virtual bool IsRule
        {
            get
            {
                return false;
            }
        }
        #endregion
    }
}
